package xcmg.device.web.threeGuaranteesPur;

import com.alibaba.druid.support.json.JSONUtils;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import xcmg.device.dao.entity.threeGuaranteesPur.ThreeGuaranteesOutDO;
import xcmg.device.infra.AuthCode;
import xcmg.device.infra.BasicController;
import xcmg.device.infra.ErrorCode;
import xcmg.device.service.threeGuaranteesPur.ThreeGuaranteesOutService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.delivery.ManualFinishVO;
import xcmg.device.service.vo.threeGuaranteesOut.SapOrderSeearchParam;
import xcmg.device.service.vo.threeGuaranteesOut.ThreeGuaranteesOutDetailBarcodeSaveParam;
import xcmg.device.service.vo.threeGuaranteesPur.ThreeGuaranteesOutAddVO;
import xcmg.device.service.vo.threeGuaranteesPur.ThreeGuaranteesOutDetailBarcodeResultVO;
import xcmg.device.service.vo.threeGuaranteesPur.ThreeGuaranteesOutVO;
import xcmg.device.util.JedisUtils;
import yb.ecp.fast.infra.annotation.FastMappingInfo;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.infra.log.LogHelper;
import yb.ecp.fast.infra.util.ListUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("/threeGuaranteesOut")
public class ThreeGuaranteesOutController extends BasicController{
    @Autowired
    private ThreeGuaranteesOutService threeGuaranteesOutService;

    @Autowired
    private JedisUtils jedisUtils;

    //重复操作加校验的时间间隔
    private static Long DULIP_OPERATE_TIME = 10 * 1000L;

    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @ApiOperation(value = "增加三包出库申请")
    @FastMappingInfo(needLogin = true,code = AuthCode.StockOut.GUARANTEES_OUT_ADD)
    public ActionResult submit (@RequestBody ThreeGuaranteesOutAddVO threeGuaranteesOutAddVO)throws Exception {
        FunctionResult result = new FunctionResult();
        ErrorCode errorCode;
        try {
            errorCode = threeGuaranteesOutService.add(threeGuaranteesOutAddVO, getOrgId(), getUserId());
            result.setCode(errorCode);
            result.setValue(errorCode.getDesc());
        }catch (Exception exc){
            result.setCode(ErrorCode.Failure);
            result.setValue(exc.getMessage());
            LogHelper.monitor(getExceptionAllinformation(exc));
        }
        return actionResult(result.getCode(), result.getValue());
    }

    @RequestMapping(value = "/remove",method = RequestMethod.POST)
    @ApiOperation(value = "删除三包出库申请")
    @FastMappingInfo(needLogin = true,code = AuthCode.StockOut.GUARANTEES_OUT_DEL)
    public ActionResult remove(@RequestBody String[] ids)throws Exception {
        FunctionResult result = new FunctionResult();
        ErrorCode errorCode;
        try {
            errorCode = threeGuaranteesOutService.remove(Arrays.asList(ids), getOrgId());
            result.setCode(errorCode);
            result.setValue(errorCode.getDesc());
        }catch (Exception exc){
            result.setCode(ErrorCode.Failure);
            result.setValue(exc.getMessage());
        }
        return actionResult(result.getCode(), result.getValue());
    }

    @RequestMapping(value = "/update",method = RequestMethod.POST)
    @ApiOperation(value = "更新三包出库申请")
    @FastMappingInfo(needLogin = true,code = AuthCode.StockOut.GUARANTEES_OUT_EDIT)
    public ActionResult update(@RequestBody ThreeGuaranteesOutAddVO threeGuaranteesOutAddVO)throws Exception{
        if(threeGuaranteesOutAddVO.getHeaderInfo().getId() == null){
            return actionResult(ErrorCode.ThreeGuaranteesOut);
        }
        return actionResult(threeGuaranteesOutService.update(threeGuaranteesOutAddVO, getOrgId()));
    }

    @RequestMapping(value = "/list",method = RequestMethod.POST)
    @ApiOperation(value = "三包出库申请列表")
    @FastMappingInfo(needLogin = true)
    public ActionResult list(@RequestBody SearchCommonVO<ThreeGuaranteesOutVO> condition) throws Exception {
        ThreeGuaranteesOutVO threeGuaranteesOutVO=condition.getFilters();
        if(threeGuaranteesOutVO==null){
            threeGuaranteesOutVO=new ThreeGuaranteesOutVO();
        }
        String deptId = getDeptId();
        String orgId = getOrgId();
        threeGuaranteesOutVO.setOrgId(orgId);
        condition.setFilters(threeGuaranteesOutVO);
        PageCommonVO pageCommonVO=threeGuaranteesOutService.list(condition,orgId,deptId);
        return actionValueResult(pageCommonVO.getPageInfo());
    }

    @RequestMapping(value = "/item",method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult item(String id){
        if(StringUtils.isEmpty(id)){
            return actionResult(ErrorCode.IllegalArument);
        }
        return actionResult(ErrorCode.Success,threeGuaranteesOutService.item(id));
    }

    /**
     * @Des 打印时显示的三包出库单信息
     * @Date 2020/12/29 16:49
     * @Author wangzhaoyu
     * @Param []
     * @Return yb.ecp.fast.infra.infra.ActionResult
     */
    @RequestMapping(value = "/itemPrintInfo",method = RequestMethod.GET)
    @FastMappingInfo(needLogin = true)
    public ActionResult itemPrintInfo(String id){
        if(StringUtils.isEmpty(id)){
            return actionResult(ErrorCode.IllegalArument);
        }
        ThreeGuaranteesOutAddVO guaranteesOut = threeGuaranteesOutService.itemPrintInfo(id);
        return actionResult(ErrorCode.Success,guaranteesOut);
    }

    //导出
    @RequestMapping(value = "/export",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true,code = AuthCode.StockOut.GUARANTEES_OUT_EXPORT)
    public void export(String[] ids)throws Exception {
        threeGuaranteesOutService.export(Arrays.asList(ids));
    }

    @RequestMapping(value = "/exportAll",method = RequestMethod.POST)
    @FastMappingInfo(needLogin = true,code = AuthCode.StockOut.GUARANTEES_OUT_EXPORT)
    public void exportAll(ThreeGuaranteesOutVO condition)throws Exception {
        if(condition == null){
            condition = new ThreeGuaranteesOutVO();
        }
        condition.setOrgId(getOrgId());
        threeGuaranteesOutService.exportAll(condition);
    }

    @RequestMapping(value = "/manualFinish", method = RequestMethod.POST)
    @ApiOperation("手动完成发货单")
    public ActionResult manualFinish(@RequestBody ManualFinishVO manualFinishVO) throws Exception
    {
        return actionResult(threeGuaranteesOutService.manualFinish(manualFinishVO.getBillNo(), manualFinishVO.getMaterialsNo(), getOrgId()));
    }

    private String getExceptionAllinformation(Exception ex){
        String sOut = "\r\n";
        StackTraceElement[] trace = ex.getStackTrace();
        for (StackTraceElement s : trace) {
            sOut += "\tat " + s + "\r\n";
        }
        return sOut;
    }

    @RequestMapping(value = "/listSapOrder", method = RequestMethod.POST)
    public ActionResult listSapOrder(@RequestBody SapOrderSeearchParam model) {
        LogHelper.monitor("sapOrders查询参数：" + model.toString());
        if (null == model) {
            return actionResult(ErrorCode.IllegalArument);
        }
        ActionResult actionResult = null;
        try {
            actionResult = actionResult(ErrorCode.Success,
                threeGuaranteesOutService.listSapOrderByThreeApply(model));
        } catch (Exception e) {
            actionResult(ErrorCode.Failure, e.getMessage());
            LogHelper.fatal("ThreeGuaranteesOutController#listSapOrder is error.", e);
        }
        return actionResult;
    }

    /**
     * 根据出库单详情id获取详情下存在的条码
    * @return
     */
    @RequestMapping(value = "/outDetailBarcodes/{detailId}" ,method = RequestMethod.GET)
    public ActionResult outDetailBarcodes(@PathVariable String detailId){
        ThreeGuaranteesOutDetailBarcodeResultVO result = threeGuaranteesOutService.outDetailBarcodes(detailId);
        ActionResult<ThreeGuaranteesOutDetailBarcodeResultVO> resp = actionValueResult(result);
        return resp;
    }

    /**
     * 编辑出库单的条码信息
     * */
    @RequestMapping(value = "/outDetailBarcodes/edit" , method = RequestMethod.POST)
    public ActionResult outDetailBarcodesEdit(@RequestBody ThreeGuaranteesOutDetailBarcodeSaveParam param){
        long currentTimed = System.currentTimeMillis();
        // 重复点击校验
        String dulpiCheckKey = "outDetailBarcodes-edit"+param.getDetailId();
        try{
            boolean dulpiCheck = checkDulpiOperate(dulpiCheckKey, currentTimed);
            if(!dulpiCheck){
                return actionResult(ErrorCode.Failure,"程序处理中,请勿重复操作","程序处理中,请勿重复操作");
            }
            // 获取出库单detail记录，对比记录中的数量与传参的参数中数量总值，如果总值超过detail表中的数值则不允许提交
            ActionResult checkResult = threeGuaranteesOutService.outDetailBarcodesEditParamCheck(param);
            if(!successActionResult(checkResult)){
                return checkResult;
            }
            // 提交条码记录，如果该条记录有id则进行更新操作，如果没有id则进行插入操作
            ActionResult actionResult = null;
            try {
                actionResult = threeGuaranteesOutService.editBarcodes(param);
            } catch (Exception e) {
            }
            if(!successActionResult(actionResult)){
                return actionResult;
            }
            // 插入完成后返回操作结果,用于前端刷新页面
            ThreeGuaranteesOutDetailBarcodeResultVO result = threeGuaranteesOutService.outDetailBarcodes(param.getDetailId());
            ActionResult<ThreeGuaranteesOutDetailBarcodeResultVO> resp = actionValueResult(result);
            //删除掉缓存的占用
            jedisUtils.delete(dulpiCheckKey);
            return resp;
        }catch (Exception e){
            jedisUtils.delete(dulpiCheckKey);
            LogHelper.error("编辑出库单条码异常"+JSONUtils.toJSONString(e), ErrorCode.RequestIdError.getCode());
            return actionValueResult("服务器异常,请联系管理人员");
        }
    }

    /**
     * 判断是否重复点击，如果重复点击返回false,否则占有当前操作并返回true*/
    private boolean checkDulpiOperate(String redisKey,Long currentTime){
        //判断key是否已经存在缓存，如果已经存在则对比缓存中的过期时间，超过过期时间则手动清除缓存然后保存新的缓存
        if (jedisUtils.exists(redisKey)) {
            Long redisTime = (Long) jedisUtils.get(redisKey);
            //判断是否超时，如果没有超时就返回false
            if(currentTime - redisTime < DULIP_OPERATE_TIME){
                return false;
            }else{
                //如果超时了则进行清空操作
                jedisUtils.delete(redisKey);
            }
        }else{
            jedisUtils.set(redisKey,currentTime,DULIP_OPERATE_TIME/1000);
        }
        return true;
    }

    @GetMapping("/findBillNoByCrmOrder")
    public ActionResult findBillNoByCrmOrder(String crmOrder) throws Exception {
        String billNo = "";
        List<ThreeGuaranteesOutDO> doList = threeGuaranteesOutService.listByCrmOrder(crmOrder, getOrgId());
        if (!ListUtil.isNullOrEmpty(doList)){
            billNo = doList.get(0).getGuaranteesOutNo();
        }
        return actionValueResult(billNo);
    }

    @GetMapping("/itemList")
    @FastMappingInfo(needLogin = true)
    public ActionResult itemList(String[] ids){
        List<ThreeGuaranteesOutAddVO> threeGuaranteesOutAddVOList = new ArrayList<>();
        for (String id : ids) {
            ThreeGuaranteesOutAddVO item = threeGuaranteesOutService.item(id);
            threeGuaranteesOutAddVOList.add(item);
        }
        return actionValueResult(threeGuaranteesOutAddVOList);
    }


}
